package com.yanqu.road.server.manager.tomb.event;

import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUnion;
import com.yanqu.road.logic.activity.tomb.config.entity.ActivityTombFloor;
import com.yanqu.road.pb.tomb.Tomb;
import com.yanqu.road.server.manager.tomb.Position;
import com.yanqu.road.server.manager.tomb.TombMaze;
import com.yanqu.road.logic.activity.tomb.config.entity.ActivityTombEvent;
import com.yanqu.road.server.manager.tomb.entity.*;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.List;

public class EliteNpcBattle implements IEvent {
    @Override
    public boolean canStand(DbTombUser dbTombUser, TombMaze tombMaze, Position position) {
        if (position.isDone()) {
            return true;
        }
        DbTombPosition dbTombPosition = tombMaze.getDbTombPosition(position.getKey());
        if (dbTombPosition == null) {
            return true;
        }
        if (!dbTombPosition.isAlive()) {
            return true;
        }
        return false;
    }

    @Override
    public boolean canThrough(DbTombUser dbTombUser, TombMaze tombMaze, Position position) {
        return canStand(dbTombUser, tombMaze, position);
    }

    @Override
    public boolean canExplore(DbTombUser dbTombUser, TombMaze tombMaze, Position position) {
        if (this.canStand(dbTombUser, tombMaze, position)) {
            return false;
        }
        DbTombPosition dbTombPosition = tombMaze.getDbTombPosition(position.getKey());
        if (dbTombPosition == null) {
            return false;
        }
        return false;
    }

    @Override
    public void detail(TombMaze tombMaze, DbTombUser dbTombUser, Position position, Tomb.PositionTemp.Builder positionTempBuilder, Tomb.TombEventExploreResp.Builder builder) {
        DbTombPosition dbTombPosition = tombMaze.getDbTombPosition(position.getKey());
        if (dbTombPosition == null) {
            return;
        }

        ActivityTombEvent activityTombEvent = tombMaze.getConfig().getEvent(dbTombPosition.getEventId());
        long digUser = dbTombPosition.acquireDigUser();
        DbTombUser digDbTombUser = tombMaze.getActivity().getDbData().getDbTombUser(digUser);
        positionTempBuilder.setDigUser(digDbTombUser.toEventUserInfoBuilder());
        positionTempBuilder.setEventConfig(activityTombEvent.getEventConfigBuilder());
        positionTempBuilder.setMaxHp(dbTombPosition.getMaxHp());
        positionTempBuilder.setHp(dbTombPosition.getCurrentHp());
        positionTempBuilder.setAttackTimes(dbTombPosition.getAttackTimes(dbTombUser.getUserId()));
        positionTempBuilder.setEnum(position.getpEnum());
        positionTempBuilder.setEventEnum(position.geteType());
        positionTempBuilder.setIsOver(false);
        positionTempBuilder.setOverTime(dbTombPosition.getCreateTime() + tombMaze.getConfig().getConfig().getTOMB_BOSS_PROTECT_TIME() * DateHelper.SECOND_MILLIONS);
        positionTempBuilder.setLastAttackTimestamp(dbTombPosition.getLastOperateTime(dbTombUser.userId));
        String key = String.format("%d_%d_%d_%d", dbTombUser.getGroupId(), tombMaze.getFloor(), position.getRow(), position.getColumn());
        builder.addAllEventUserInfo(tombMaze.getEventUserInfoList(dbTombUser, key));
    }

    @Override
    public void explore(TombMaze tombMaze, DbTombUser dbTombUser, DbTombPosition dbTombPosition, Position position, ActivityTombEvent activityTombEvent, Tomb.PositionTemp.Builder positionTempBuilder, Tomb.TombEventExploreResp.Builder builder) {
        long totalActiveUserAbility = tombMaze.getActivity().getTotalActiveUserAbility(dbTombUser.getGroupId());
        List<Integer> tombBossHpParam = tombMaze.getConfig().getConfig().getTOMB_BOSS_HP_PARAM();
        int p = tombBossHpParam.get(1);
        double maxHp = (double) totalActiveUserAbility * (double) p / (double) 1000;
        maxHp = Math.ceil(maxHp);

        dbTombPosition.setMaxHp((long) maxHp);
        dbTombPosition.setCurrentHp((long) maxHp);

        positionTempBuilder.setMaxHp(dbTombPosition.getMaxHp());
        positionTempBuilder.setHp(dbTombPosition.getCurrentHp());
        positionTempBuilder.setEnum(position.getpEnum());
        positionTempBuilder.setEventEnum(position.geteType());
        tombMaze.getDbTombMaze().setEliteNpcEvent(position.getKey());
        tombMaze.getDbTombMaze().refreshUpdateTime();


        Tomb.TombEliteNpcInfoPush.Builder tombMazeEliteNpcInfo = tombMaze.getEliteNpcInfo(dbTombUser);
        tombMazeEliteNpcInfo.setScope(1);
        tombMazeEliteNpcInfo.setAction(1);
        tombMaze.eventEliteNpcInfoSyncPush(tombMazeEliteNpcInfo, dbTombUser, false);

        //日志
        DbTombLog dbTombLog = DbTombLog.newInstance();
        dbTombLog.setUid(String.valueOf(tombMaze.getActivityId()));
        dbTombLog.setFloor(tombMaze.getFloor());
        dbTombLog.setFromUserId(dbTombUser.getUserId());
        dbTombLog.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Find_Elite_Npc_VALUE);
        dbTombLog.setEventId(activityTombEvent.getId());
        dbTombLog.setValue1(activityTombEvent.getNpcId());
        dbTombLog.setEnergyChange(-activityTombEvent.getConsumeEnergy());
        dbTombLog.setEnergy(dbTombUser.getEnergy(tombMaze.getConfig().getConfig()));
        dbTombLog.setX(position.getRow());
        dbTombLog.setY(position.getColumn());
        dbTombLog.setDescription("探索到了精英");
        dbTombLog.setGroupId(dbTombUser.getGroupId());
        tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog, true);


        //日志
        DbTombLog dbTombLog1 = DbTombLog.newInstance();
        dbTombLog1.setUid(dbTombUser.getUserInfo().getUnionUid());
        dbTombLog1.setFloor(tombMaze.getFloor());
        dbTombLog1.setFloor(tombMaze.getFloor());
        dbTombLog1.setFromUserId(dbTombUser.getUserId());
        dbTombLog1.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Find_Elite_Npc_VALUE);
        dbTombLog1.setEventId(activityTombEvent.getId());
        dbTombLog1.setValue1(activityTombEvent.getNpcId());
        dbTombLog1.setEnergyChange(-activityTombEvent.getConsumeEnergy());
        dbTombLog1.setEnergy(dbTombUser.getEnergy(tombMaze.getConfig().getConfig()));
        dbTombLog1.setX(position.getRow());
        dbTombLog1.setY(position.getColumn());
        dbTombLog1.setGroupId(dbTombUser.getGroupId());
        dbTombLog1.setDescription("探索到了精英");
        tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog1, false);

        Tomb.TombNotifyPush.Builder notifyPushBuilder = Tomb.TombNotifyPush.newBuilder();
        notifyPushBuilder.setFloor(tombMaze.getFloor());
        notifyPushBuilder.setNpcId(activityTombEvent.getNpcId());
        notifyPushBuilder.setType(1);
        notifyPushBuilder.setGroupId(dbTombUser.getGroupId());
        tombMaze.notifyPush(notifyPushBuilder);
    }

    @Override
    public void display(DbTombUser dbTombUser, TombMaze tombMaze, Position position, Tomb.PositionTemp.Builder p) {
        DbTombPosition dbTombPosition = tombMaze.getDbTombPosition(position.getKey());
        if (dbTombPosition == null) {
            p.setIsOver(true);
            return;
        }
        if (!dbTombPosition.isAlive()) {
            p.setIsOver(true);
            return;
        }

        p.setMaxHp(dbTombPosition.getMaxHp());
        p.setHp(dbTombPosition.getCurrentHp());
        ActivityTombEvent event = tombMaze.getConfig().getEvent(dbTombPosition.getEventId());
        p.setEventConfig(event.getEventConfigBuilder());
        p.setIsOver(false);
    }


    @Override
    public void info(TombMaze tombMaze, DbTombUser dbTombUser, DbTombPosition dbTombPosition, Position position, ActivityTombEvent activityTombEvent, Tomb.PositionTemp.Builder positionTempBuilder, Tomb.TombEventInfoResp.Builder builder) {

        long digUser = dbTombPosition.acquireDigUser();
        DbTombUser digDbTombUser = tombMaze.getActivity().getDbData().getDbTombUser(digUser);
        positionTempBuilder.setDigUser(digDbTombUser.toEventUserInfoBuilder());
        positionTempBuilder.setEventConfig(activityTombEvent.getEventConfigBuilder());
        positionTempBuilder.setMaxHp(dbTombPosition.getMaxHp());
        positionTempBuilder.setHp(dbTombPosition.getCurrentHp());
        positionTempBuilder.setAttackTimes(dbTombPosition.getAttackTimes(dbTombUser.getUserId()));
        String key = String.format("%d_%d_%d_%d", dbTombUser.getGroupId(), tombMaze.getFloor(), position.getRow(), position.getColumn());
        builder.addAllEventUserInfo(tombMaze.getEventUserInfoList(dbTombUser, key));
    }

    @Override
    public void touch(TombMaze tombMaze, DbTombUser dbTombUser, DbTombPosition dbTombPosition, Position position, ActivityTombEvent activityTombEvent, Tomb.PositionTemp.Builder positionTempBuilder, Tomb.TombEventTouchResp.Builder builder, Tomb.TombEventTouchReq req) {

        boolean alive = dbTombPosition.isAlive();
        if (!alive) {
            builder.setRet(GameErrorCode.E_TOMB_TARGET_IS_NOT_ALIVE);
            return;
        }

        /**
         * 如果自己不是第一个来的
         */

        //6.4.0皇陵优化防外挂 除了第一个发现精英怪的玩家之外需要一个cd才能打
        //6.5.0皇陵优化防外挂 除了第一个发现精英怪的玩家的同商会玩家 之外需要一个cd才能打
        if (dbTombPosition.acquireDigUser() != dbTombUser.getUserId()) {
            //拿出当前攻击精英的玩家的商会
            UnionActivityGroupUnion attackUnion = Cross2UnionActivityGroupMgr.getUnionData(dbTombUser.getActivityId(), dbTombUser.userId);
            //如果没有就错误码了
            if (attackUnion == null) {
                builder.setRet(GameErrorCode.E_TOMB_ACTIVITY_NOT_JOIN_UNION);
                return;
            }
            //如果当前攻击精英boss的玩家的商会不是于第一个发现精英boss的商会 就需要一个保护时间
            if (!attackUnion.getUserMap().keySet().contains(dbTombPosition.acquireDigUser())) {
                int protectTime = tombMaze.getActivity().getConfig().getConfig().getTOMB_BOSS_PROTECT_TIME();
                if (System.currentTimeMillis() < dbTombPosition.getCreateTime() + protectTime * DateHelper.SECOND_MILLIONS){
                    builder.setRet(GameErrorCode.E_TOMB_BATTLE_EVENT_PROTECT_TIME);
                    return;
                }
            }
            //同商会的玩家就不进保护了
        }

        //攻击间隔 如果两次攻击时间间隔小于攻击间隔时间就返回错误码
        long atk_cd_time = DateHelper.SECOND_MILLIONS * tombMaze.getActivity().getConfig().getConfig().getTOMB_BOSS_ATK_CD_TIME();
        boolean inCd = dbTombPosition.checkOperationTimeInCd(dbTombUser.userId, atk_cd_time);
        if (inCd){
            builder.setRet(GameErrorCode.E_TOMB_BATTLE_EVENT_IN_CD);
            return;
        }

        //扣除体力
        long costEnergy = 0;
        if (tombMaze.checkNeedCostEnergy(dbTombPosition, dbTombUser)) {
            List<Integer> tombEnergyCostSpecial = tombMaze.getActivity().getConfig().getConfig().getTOMB_ENERGY_COST_SPECIAL();
            int p1 = tombEnergyCostSpecial.get(0);
            int p2 = tombEnergyCostSpecial.get(1);
            ActivityTombFloor activityTombFloor = tombMaze.getActivity().getConfig().getFloor(tombMaze.getFloor());
            PositionInfo positionInfo = dbTombPosition.acquireEventInfo(dbTombUser.getUserId());

            long attackTimes = positionInfo.getAttackTimes();

            long e = activityTombFloor.getEnergy() + attackTimes * p1;
            e = Math.min(e, p2);
            costEnergy = e;
            boolean b = tombMaze.costEnergy(dbTombUser, (int) e, activityTombEvent.getId());
            if (!b) {
                builder.setRet(GameErrorCode.E_TOMB_USER_NOT_ENOUGH_ENERGY);
                return;
            }
        }
        //扣完体力马上给玩家上cd记录
        dbTombPosition.addOperationTime(dbTombUser.getUserId(), System.currentTimeMillis());

        long attack = dbTombUser.getTotalAttack();
        attack = dbTombPosition.underAttack(attack);
        if (attack > 0) {
            dbTombPosition.addEventInfo(dbTombUser.getUserId(), dbTombUser.getUserInfo().getNickName(), attack);
        }
        Property property = null;

        boolean isKilled = false;
        alive = dbTombPosition.isAlive();
        if (alive) {
            property = new Property();
        } else if (attack > 0) {
            isKilled = true;
            dbTombPosition.setFinishUserId(dbTombUser.getUserId());
            position.setKillUserId(dbTombUser.getUserId());

            property = new Property(activityTombEvent.getReward());
            Property randMonsterReward = activityTombEvent.randMonsterReward();
            property.addProperty(randMonsterReward);

            position.seteType(Tomb.EventEnum.EVENT_ENTER_VALUE);
            position.setpEnum(Tomb.PositionEnum.POSITION_EVENT_VALUE);
            tombMaze.updateGrip(position);

            dbTombPosition.seteType(position.geteType());
            dbTombPosition.refreshUpdateTime();

//            tombMaze.refundUnAttackDigUserEnergy(dbTombPosition);
        }
        positionTempBuilder.setMaxHp(dbTombPosition.getMaxHp());
        positionTempBuilder.setHp(dbTombPosition.getCurrentHp());
        positionTempBuilder.setEnum(position.getpEnum());
        positionTempBuilder.setEventEnum(position.geteType());
        positionTempBuilder.setLastAttackTimestamp(dbTombPosition.getLastOperateTime(dbTombUser.userId));
        if (dbTombPosition.getFinishUserId() > 0) {
            DbTombUser dbTombUser1 = tombMaze.getActivity().getDbData().getDbTombUser(dbTombPosition.getFinishUserId());
            if (dbTombUser1 != null) {
                positionTempBuilder.setFinishUser(dbTombUser1.toEventUserInfoBuilder());
            }
        }


        if (attack > 0) {
            builder.setValue(attack);
            tombMaze.handleAttackScore(attack, dbTombPosition.getMaxHp(), activityTombEvent, property, dbTombUser);
            String key = String.format("%d_%d_%d_%d", dbTombUser.getGroupId(), tombMaze.getFloor(), position.getRow(), position.getColumn());
            tombMaze.eventBattleSyncPush(dbTombUser, attack, dbTombPosition.getCurrentHp(), key, false);
            dbTombPosition.refreshUpdateTime();
            position.refreshTimestamp();


            Tomb.TombEliteNpcInfoPush.Builder tombMazeEliteNpcInfo = tombMaze.getEliteNpcInfo(dbTombUser);
            tombMazeEliteNpcInfo.setScope(1);
            if (position.geteType() == Tomb.EventEnum.EVENT_ENTER_VALUE) {
                tombMazeEliteNpcInfo.setAction(2);
            }
            tombMaze.eventEliteNpcInfoSyncPush(tombMazeEliteNpcInfo, dbTombUser, false);

            tombMaze.addProperty(property, dbTombUser);
            builder.setRewards(PropertyHelper.parsePropertyToString(property));
            if (isKilled) {

                //日志
                DbTombLog dbTombLog = DbTombLog.newInstance();
                dbTombLog.setUid(String.valueOf(tombMaze.getActivityId()));
                dbTombLog.setFloor(tombMaze.getFloor());
                dbTombLog.setFromUserId(dbTombUser.getUserId());
                dbTombLog.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Battle_VALUE);
                dbTombLog.setEventId(activityTombEvent.getId());
                dbTombLog.setValue(attack);
                dbTombLog.setValue1(activityTombEvent.getNpcId());
                dbTombLog.setRewards(builder.getRewards());
                dbTombLog.setEnergyChange(-activityTombEvent.getConsumeEnergy());
                dbTombLog.setEnergy(dbTombUser.getEnergy(tombMaze.getConfig().getConfig()));
                dbTombLog.setX(position.getRow());
                dbTombLog.setY(position.getColumn());
                dbTombLog.setDescription("杀死精英守卫");
                dbTombLog.setGroupId(dbTombUser.getGroupId());
                dbTombLog.setStatus(1);
                tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog, true);


                //日志
                DbTombLog dbTombLog1 = DbTombLog.newInstance();
                dbTombLog1.setUid(String.valueOf(dbTombUser.getUserId()));
                dbTombLog1.setFloor(tombMaze.getFloor());
                dbTombLog1.setFromUserId(dbTombUser.getUserId());
                dbTombLog1.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Battle_VALUE);
                dbTombLog1.setEventId(activityTombEvent.getId());
                dbTombLog1.setValue(attack);
                dbTombLog1.setValue1(activityTombEvent.getNpcId());
                dbTombLog1.setRewards(builder.getRewards());
                dbTombLog1.setEnergyChange(-activityTombEvent.getConsumeEnergy());
                dbTombLog1.setEnergy(dbTombUser.getEnergy(tombMaze.getConfig().getConfig()));
                dbTombLog1.setX(position.getRow());
                dbTombLog1.setY(position.getColumn());
                dbTombLog1.setDescription("杀死精英守卫");
                dbTombLog1.setGroupId(dbTombUser.getGroupId());
                dbTombLog1.setStatus(1);
                tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog1, false);


                //日志
                DbTombLog dbTombLog2 = DbTombLog.newInstance();
                dbTombLog2.setUid(String.valueOf(tombMaze.getActivityId()));
                dbTombLog2.setFloor(tombMaze.getFloor());
                dbTombLog2.setFromUserId(dbTombUser.getUserId());
                dbTombLog2.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Find_Downstairs_VALUE);
                dbTombLog2.setEventId(activityTombEvent.getId());
                dbTombLog2.setValue(attack);
                dbTombLog2.setX(position.getRow());
                dbTombLog2.setY(position.getColumn());
                dbTombLog2.setGroupId(dbTombUser.getGroupId());
                dbTombLog2.setDescription("找到了下楼楼梯");
                tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog2, true);


                Tomb.TombNotifyPush.Builder notifyPushBuilder = Tomb.TombNotifyPush.newBuilder();
                notifyPushBuilder.setFloor(tombMaze.getFloor());
                notifyPushBuilder.setNpcId(activityTombEvent.getNpcId());
                notifyPushBuilder.setType(2);
                notifyPushBuilder.setGroupId(dbTombUser.getGroupId());
                tombMaze.notifyPush(notifyPushBuilder);

            } else {
                //日志
                DbTombLog dbTombLog = DbTombLog.newInstance();
                dbTombLog.setUid(String.valueOf(dbTombUser.getUserId()));
                dbTombLog.setFloor(tombMaze.getFloor());
                dbTombLog.setFromUserId(dbTombUser.getUserId());
                dbTombLog.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Battle_VALUE);
                dbTombLog.setEventId(activityTombEvent.getId());
                dbTombLog.setValue(attack);
                dbTombLog.setValue1(activityTombEvent.getNpcId());
                dbTombLog.setRewards(builder.getRewards());
                dbTombLog.setGroupId(dbTombUser.getGroupId());
                dbTombLog.setEnergyChange(-activityTombEvent.getConsumeEnergy());
                dbTombLog.setEnergy(dbTombUser.getEnergy(tombMaze.getConfig().getConfig()));
                dbTombLog.setX(position.getRow());
                dbTombLog.setY(position.getColumn());
                dbTombLog.setDescription("攻击精英守卫");
                tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog, false);
            }

            //发到游戏服写日志
            Tomb.TombLogCrossToGameReq.Builder logBuilder = Tomb.TombLogCrossToGameReq.newBuilder();
            logBuilder.setLEnum(Tomb.GameTombLogEnum.BATTLE);
            logBuilder.setUserId(dbTombUser.getUserId());
            logBuilder.setActivityId(tombMaze.getActivityId());
            logBuilder.setUnionUid(dbTombUser.getUserInfo().getUnionUid());
            logBuilder.setFloor(dbTombUser.getFloor());
            logBuilder.setX(position.getRow());
            logBuilder.setY(position.getColumn());
            logBuilder.setHp(dbTombUser.getHp());
            logBuilder.setTimestamp(System.currentTimeMillis());
            Tomb.TombLogBattle.Builder battle = Tomb.TombLogBattle.newBuilder();
            battle.setIsPvp(0);
            battle.setAttack(attack);
            battle.setBattleId(activityTombEvent.getNpcId());
            battle.setRivalMaxHp(dbTombPosition.getMaxHp());
            battle.setRivalHp(dbTombPosition.getCurrentHp());
            battle.setCostEnergy(0);
            if (isKilled) {
                battle.setIsKill(1);
            } else {
                battle.setIsKill(0);
            }
            logBuilder.setBattle(battle);
            Tomb.TombLogMove.Builder logMoveBuilder = Tomb.TombLogMove.newBuilder();
            logMoveBuilder.setEventId(dbTombPosition.getEventId());
            logBuilder.setMove(logMoveBuilder);
            tombMaze.getActivity().sendLogToGame(dbTombUser, logBuilder);

        }


    }
}
